package com.grgbanking.it.base;

import java.io.Serializable;  
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.grgbanking.it.base.IBaseDao;
import com.grgbanking.it.common.util.HibernateUtil;

/**
 * BaseDaoImpl 定义DAO的通用操作的实现
 * 
 * @author JRainbow 
 */
public class BaseDao<T,PK extends Serializable> extends HibernateDaoSupport implements IBaseDao<T,PK> {

	private Class<T> clazz;

	public BaseDao() {
		ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
		clazz = (Class<T>) type.getActualTypeArguments()[0];
	}

	
    public void save(T entity) {           
    	getHibernateTemplate().save(entity);   
    }   
     
    public void update(T entity) {
    	getHibernateTemplate().update(entity);
	}
  
    
    public void delete(T entity) {   
    	getHibernateTemplate().delete(entity);
    }   
    
     
    public void deleteById(PK id) {  
        getHibernateTemplate().delete(this.findById(id));  
    }  
    
    @Override
	public void virtualDelete(PK id) throws Exception {
		String hql = HibernateUtil.createVirtualDeleteHQL(clazz, id);
		this.executeHQL(hql);
	}
       
    
    public void saveOrUpdate(T entity) {   
    	getHibernateTemplate().saveOrUpdate(entity);    
    }   
  
    
    public T findById(PK id) {   
    	 return (T) getHibernateTemplate().get(clazz, id);   
    }   
  
    public T findOneByHQL(String hql){
    	List<T> list = findByHql(hql);
    	if(list.size() > 0){
    		return list.get(0);
    	}
    	return null;
    }
    
    /**
	 * 根据List保存
	 * 
	 * @param list
	 *            对象列表
	 */
	public void save(List<T> list) throws Exception {
		getHibernateTemplate().saveOrUpdateAll(list);
	}

	/**
	 * 增加或更新集合中的全部实体
	 * 
	 * @param entities
	 *            对象集合
	 */
	public void saveOrUpdateAll(Collection<T> entities) throws Exception {
		getHibernateTemplate().saveOrUpdateAll(entities);
	}
    
   
    @SuppressWarnings("unchecked")
	public List<T> findByHql(String hql) {  
        return getHibernateTemplate().find(hql);  
    }  
  
   
    @SuppressWarnings(value = { "unchecked" })
    public List<T> pageByHQL(final String hql, final Integer start,final Integer limit) {        
    	return getHibernateTemplate().execute(new HibernateCallback() {   
            public Object doInHibernate(Session session)   
                    throws HibernateException, SQLException {   
                Query query = session.createQuery(hql);   
                query.setFirstResult(start);   
                query.setMaxResults(limit);  
                return query.list();   
            }   
        }); 
    }

	public Long getTotalByHQL(String hql) {
		return (Long) getHibernateTemplate().find("select count(*) " + hql).get(0);
	}   
	
	public Long getTotalBySQL(String sql) {
		StringBuffer strBuf = new StringBuffer();
		strBuf.append("select count(*) as total ");
		strBuf.append("from (").append(sql).append(") ta");
		Query query = this.getSession().createSQLQuery(strBuf.toString());
		Object oo = query.uniqueResult();
		Long total = Long.valueOf(0);
		if (oo != null) {
			BigDecimal ss = new BigDecimal(oo.toString());
			total = ss.longValue();
		}
		return total;
	}
	
	public List<Map> listBySQL(String sql) throws Exception {
		Query query = this.getSession().createSQLQuery(sql).setResultTransformer(
				Transformers.ALIAS_TO_ENTITY_MAP);
		return query.list();
	}
	
	public List<T> findBySQL(String sql) throws Exception {
		Query query = this.getSession().createSQLQuery(sql)
				.setResultTransformer(Transformers.aliasToBean(clazz));

		return query.list();
	}
	
	public List<?> pageBySQL(String sql, Integer start, Integer limit) {
		Query query = this.getSession().createSQLQuery(sql)
				.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		return query.setMaxResults(limit).setFirstResult(start).list();
	}
	
	/**
	 * 使用HQL语句直接增加、更新、删除实体(不支持级联)
	 * 
	 * @param hql
	 * @return 操作成功的记录条数
	 */
	public int executeHQL(String hql) throws Exception {
		return getHibernateTemplate().bulkUpdate(hql);
	}
}
